package org.flashbrighton.as3bots.views
{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.Point;
	import flash.text.*;
	import flash.utils.*;
	
	import net.hires.utils.*;
	
	import org.flashbrighton.as3bots.effects.EffectsManager;
	import org.flashbrighton.as3bots.effects.Explosion;
	import org.flashbrighton.as3bots.events.*;
	import org.flashbrighton.as3bots.models.*;
	import org.flashbrighton.as3bots.views.ui.*;
	import org.flashbrighton.as3bots.views.ui.scores.ScoreBoard;
	

	public class GameView extends Sprite
	{
		public static const SCALE_FACTOR:Number = 50; //pixels per metre
		
		public var alert:Alert;
		
		private var _model:GameModel;
		private var _arena:ArenaView;
		private var _floor:Sprite;
		private var _explosions:Sprite;
		private var _fx:EffectsManager;
		private var _botViewsByModel:Dictionary;
		private var _gemViewsByModel:Dictionary;
		private var _bombViewsByModel:Dictionary;
		
		
		public function GameView(model:GameModel)
		{
			_model = model;
			init();
		}
		
		
		public function get arenaView():ArenaView{
			return _arena;
		}
		
		private function init():void
		{
			_arena = new ArenaView();
			_floor = new Sprite();
			_explosions = new Sprite();
			_fx = new EffectsManager(_explosions);
			_botViewsByModel = new Dictionary(true);
			_gemViewsByModel = new Dictionary(true);
			_bombViewsByModel = new Dictionary(true);
			_model.addEventListener(DeadBotEvent.DEAD, removeBot);
		}
		
		
		public function addArenaView():void
		{
			//_arena.x = 30;
			_arena.y = 30;
			_floor.y = 30;
			_explosions.y = 30;
			
			addChild(_floor);
			addChild(_arena);
			addChild(_explosions);
			
			//setDebugDraw();
		}
		
		
		public function addBotView(botView:Sprite, botModel:BotModel):void
		{
			_botViewsByModel[botModel] = botView;
			_arena.addChild(botView);
		}
		
		public function addGemView(gemView:Sprite, gemModel:GemModel):void
		{
			_gemViewsByModel[gemModel]=gemView;
			gemView.x = gemModel.body.GetPosition().x * SCALE_FACTOR;
			gemView.y = gemModel.body.GetPosition().y * SCALE_FACTOR;
			_arena.addChild(gemView);
		}
				
		public function addBombView(bombView:Sprite, bombModel:BombModel):void
		{
			_bombViewsByModel[bombModel]=bombView;
			bombView.x = bombModel.body.GetPosition().x * SCALE_FACTOR;
			bombView.y = bombModel.body.GetPosition().y * SCALE_FACTOR;
			_arena.addChild(bombView);
		}
		
		public function update(e:Event=null):void
		{
			var botModel:BotModel;
			var botView:Sprite;
			var gemModel:GemModel;
			var gemView:Sprite;
			var bombModel:BombModel;
			var bombView:Sprite;
			
			// Go through body list and update sprite positions/rotations
			for each (botModel in _model.botList)
			{
				botView = _botViewsByModel[botModel];
				botView.x = botModel.body.GetPosition().x * SCALE_FACTOR;
				botView.y = botModel.body.GetPosition().y * SCALE_FACTOR;
				botView.rotation = botModel.body.GetAngle() * 180 / Math.PI;
			}

			for each (gemModel in _model.gemList)
			{
				gemView = gemModel.sprite;
				gemView.x = gemModel.body.GetPosition().x * SCALE_FACTOR;
				gemView.y = gemModel.body.GetPosition().y * SCALE_FACTOR;
			}

			for each (bombModel in _model.bombList)
			{
				bombView = bombModel.sprite;
				bombView.x = bombModel.body.GetPosition().x * SCALE_FACTOR;
				bombView.y = bombModel.body.GetPosition().y * SCALE_FACTOR;
			}

			_model.physics.drawWireframes();
		}
		
		
		public function setUI():void
		{
			var header:TextField = createHeader("TDD Bots Fight!", 18, true);
			header.x = 30;
			addChild(header);
			
			var margin:int = 15;
			var leftAlign:int = 515;
			var topAlign:int = 60;

			var scores:ScoreBoard = new ScoreBoard(_model)
			scores.x = leftAlign;
			scores.y = topAlign;
			topAlign += scores.height + margin;
			addChild(scores);
			
			var messagesHeader:TextField = createHeader("Messages:", 14);
			messagesHeader.x = leftAlign;
			messagesHeader.y = topAlign;
			topAlign += 25;
			addChild(messagesHeader);
			
			var msgPanelWidth:int =  stage.stageWidth - leftAlign - margin;
			var msgPanelHeight:int =  stage.stageHeight - topAlign - margin;
			var border:Sprite = new Sprite();
			border.graphics.lineStyle( 1, 0xa0a0a0);
			border.graphics.beginFill( 0x202020, 1 );
			border.graphics.drawRoundRect( 0 , 0, msgPanelWidth, msgPanelHeight,10,10 );
			border.graphics.endFill();
			border.x = leftAlign;
			border.y = topAlign;
			addChild(border);

			var message:TextField = Message.create();
			message.x = leftAlign + margin;
			message.y = topAlign+margin;
			message.width = msgPanelWidth - margin*2;
			message.height = msgPanelHeight - margin*2;
			addChild(message);
			
			alert = new Alert();
			alert.x = stage.stageWidth / 2;
			alert.y = stage.stageHeight / 2;
			addChild(alert);
			
			/*var stats:Stats = new Stats()
			stats.x = 700;
			addChild(stats);*/
		}
		
		
		public function addCountdown(timer:Timer, maxTime:int):void
		{
			var countdown:Countdown = new Countdown(timer, maxTime);
			countdown.x = stage.width - 15 - countdown.width;
			addChild(countdown);
		}
		
		
		public function removeBot(e:DeadBotEvent):void
		{
			_arena.removeChild(_botViewsByModel[e.botModel]);
			
			var point:Point = new Point();
			point.x = e.botModel.body.GetPosition().x * SCALE_FACTOR;
			point.y = e.botModel.body.GetPosition().y * SCALE_FACTOR;
			_fx.addBotExplosion(point, e.botModel.bot.colour);
			
		}
		
		public function removeGemView(gemModel:GemModel):void
		{
			var gemSprite:Sprite = _gemViewsByModel[gemModel];
			if(gemSprite!=null){
				_arena.removeChild(gemSprite);
				_gemViewsByModel[gemModel] = null;
			}
		}

		public function removeBombView(bombModel:BombModel):void
		{
			var bombSprite:Sprite = _bombViewsByModel[bombModel];
			if(bombSprite!=null){
				_arena.removeChild(bombSprite);
				_bombViewsByModel[bombModel] = null;
			}
			var point:Point = new Point();
			point.x = bombModel.body.GetPosition().x * SCALE_FACTOR;
			point.y = bombModel.body.GetPosition().y * SCALE_FACTOR;
			_fx.addBombExplosion(point, 0xFAFF00);
		}
		
		public function get fx():EffectsManager
		{
			return _fx;
		}
		
		
		private function createHeader(text:String, size:int=18, isBold:Boolean=false):TextField
		{
			var tf:TextField = new TextField();
			tf.embedFonts = true;
			tf.defaultTextFormat = new TextFormat("Arkitech", size, 0xFFFFFF, isBold);
			tf.autoSize = TextFieldAutoSize.LEFT;
			tf.selectable = false;
			tf.text = text;
			return tf;
		}
		
		/**
		 * display physics bodies
		 */
		private function setDebugDraw():void
		{
			var _debug:Sprite = new Sprite();
			_debug.y = 30;
			addChild(_debug);
			_model.physics.setDebugDraw(_debug);
		}
		
		
		
	}
}